-
-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: extend api with iterator for routes #41
Conversation
Forward iterator access to the routes to allow collecting them as a client. This allows eg. collecting the routes to subscribe them when using the router in an MQTT usecase. Signed-off-by: Marc Bodmer <[email protected]>
Thank you. Maybe implement |
clippy requests an implementation of into_iter() when implementing iter() Signed-off-by: Marc Bodmer <[email protected]>
Wow, thanks for your fast action. I've also forwarded into_iter() now |
See https://github.com/viz-rs/path-tree/actions/runs/9402026412/job/25895157980?pr=41#step:4:241 168 +
169 + impl IntoIterator for &PathTree<T> {
170 + type IntoIter = core::slice::Iter<'_, (T, alloc::vec::Vec<parser::Piece>)>;
171 + type Item = &(T, alloc::vec::Vec<parser::Piece>);
172 + fn into_iter(self) -> Self::IntoIter {
173 + self.iter()
174 + }
175 + } |
I'm interested in your MQTT case. Could you add a test case? |
So instead of forwarding into_iter() from the vector you would prefer the implementation of the trait? impl<T> IntoIterator for PathTree<T> {
type Item = (T, Vec<Piece>);
type IntoIter = IntoIter<(T, Vec<Piece>)>;
fn into_iter(self) -> Self::IntoIter {
self.routes.into_iter()
}
} |
It is not a 100% fit. The "problem" was that there is no root element in MQTT, as there is no leading "/" in a topic. I have used the workaround to prefix the route with "MQTT/". Would have preferred a direct usage, but this is ok. Also not all matchers are used. The following code create a rumqttc SubscribeFilter from the Pieces: // Newtype for rumqttc subscription filter to implement TryFrom locally
pub struct SubscribeFilter(rumqttc::v5::mqttbytes::v5::Filter);
impl Deref for SubscribeFilter {
type Target = rumqttc::v5::mqttbytes::v5::Filter;
fn deref(&self) -> &Self::Target {
&self.0
}
}
/// Generates MQTT subscription from `TreePath` pieces
impl TryFrom<(&Vec<Piece>, &QoS)> for SubscribeFilter {
type Error = Error;
fn try_from(value: (&Vec<Piece>, &QoS)) -> Result<Self, Self::Error> {
let mut bytes = Vec::new();
let qos = *value.1;
value.0.iter().try_for_each(|piece| match piece {
Piece::String(s) => {
bytes.extend_from_slice(s);
Ok(())
}
Piece::Parameter(_, kind) => match kind {
// single level wildcard, use like: "a/:name/b -> "a/+/b"
Kind::Normal => {
bytes.extend_from_slice(b"+");
Ok(())
}
// multi level wildcard, use like: "a/:name*" -> "a/#"
Kind::ZeroOrMore | Kind::ZeroOrMoreSegment => {
bytes.extend_from_slice(b"#");
Ok(())
}
// fail in other cases
_ => Err(Error::ParseError(
"Unsupported route expression".to_string(),
)),
},
})?;
// construct topic from bytes and remove prefix if appliable
let mut topic = from_utf8(&bytes).map_err(|e| Error::ParseError(e.to_string()))?;
topic = topic.strip_prefix("MQTT/").unwrap_or(topic);
Ok(SubscribeFilter(rumqttc::v5::mqttbytes::v5::Filter::new(
topic, qos,
)))
}
} Sure i can implement a testcase, do you have any pointers on what you have in mind? |
Signed-off-by: Marc Bodmer <[email protected]>
Yes, like clippy said: https://rust-lang.github.io/rust-clippy/master/index.html#/iter_without_into_iter |
could you please restart the build one more time? |
Thank you for sharing. |
Thank you for this library, it still was very useful |
The CI's output:
|
Hmm, i have implemented it, but clippy seems not to accept it: https://github.com/viz-rs/path-tree/pull/41/files#diff-b1a35a68f14e696205874893c07fd24fdb88882b47c23cc0e0c80a30c7d53759R267 Edit: I have now implemented IntoIterator for &PathTree, hope this works on CI |
Signed-off-by: Marc Bodmer <[email protected]>
Thank you for your work. |
Laned in v0.8.0. |
Thanks for releasing, cool! |
Forward iterator access to the routes to allow collecting them as a client. This allows eg. collecting the routes to subscribe them when using the router in an MQTT usecase.